package com.sanq.product.cab.aspects;

import com.sanq.product.cab.annotations.DataSourceAnnotation;
import com.sanq.product.cab.db.DynamicDataSourceHolder;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.reflect.MethodSignature;

import java.lang.reflect.Method;

/**
 * version: 切换数据源 主体
 * ---------------------
 *
 * <beans:bean id="dataSource" class="com.air.shop.common.db.DynamicDataSource">
 *     <property name="targetDataSources">
 *           <map key-type="java.lang.String">
 *              <entry key="master" value-ref="masterdataSource"/>
 *              <entry key="slave" value-ref="slavedataSource"/>
 *           </map>
 *     </property>
 *     <property name="defaultTargetDataSource" ref="masterdataSource"/>
 * </beans:bean>
 *
 * <beans:bean id="manyDataSourceAspect" class="com.sanq.product.cab.aspects.DataSourceAspect" />
 *
 * <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
 *
 * <aop:config>
 *     <aop:aspect id="c" ref="manyDataSourceAspect">
 *         <aop:pointcut id="tx" expression="execution(* 包名.*.*(..))"/>
 *         <aop:before pointcut-ref="tx" method="before"/>
 *     </aop:aspect>
 * </aop:config>
 *
 * @author sanq.Yan
 * @date 2020/1/26
 */

public class DataSourceAspect {

    public void before(JoinPoint point) {

        Object target = point.getTarget();
        String method = point.getSignature().getName();

        Class<?>[] classz = target.getClass().getInterfaces();

        Class<?>[] parameterTypes = ((MethodSignature) point.getSignature())
                .getMethod().getParameterTypes();

        try {
            Method m = classz[0].getMethod(method, parameterTypes);

            if (m != null && m.isAnnotationPresent(DataSourceAnnotation.class)) {

                DataSourceAnnotation data = m
                        .getAnnotation(DataSourceAnnotation.class);

                DynamicDataSourceHolder.putDataSource(data.db());
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void after(JoinPoint point) {
        DynamicDataSourceHolder.clearDataSource();
    }
}
